import routs


class ShipState:
    """
    State of a ship.

    Attributes:
        node: Node where the icebreaker is stay (if it is not moving).
        edge: Edge along which the icebreaker is moving (if it is moving).
        passed: Part of the edge that has been passed.
    """
    node: routs.Node | None
    edge: routs.Edge | None
    passed: float

    def __init__(self, node: routs.Node):
        self.node = node
        self.edge = None
        self.passed = 0.0

    def __str__(self):
        if self.edge is None:
            return f"{self.node.name}"
        elif self.passed >= 0.0:
            return f"{self.edge.node_start.name} --> {self.edge.node_end.name} ({100 * self.passed:.1f}%)"
        else:
            return f"{self.edge.node_end.name} --> {self.edge.node_start.name} ({-100 * self.passed:.1f}%)"


class TransportShipState(ShipState):
    """
    State of a transport ship.

    Attributes:
        ready: Indicates that the transport is ready for routing.
        icebreaker: Icebreaker to which the transport is attached.
    """
    ready: bool
    icebreaker: str

    def __init__(self, node: routs.Node):
        super().__init__(node)
        self.ready = False
        self.icebreaker = ""

    def __str__(self):
        if self.edge is None:
            if self.ready:
                return f"{self.node.name} (ready)"
            else:
                return f"{self.node.name}"
        elif self.passed >= 0.0:
            return f"{self.edge.node_start.name} --> {self.edge.node_end.name} ({100 * self.passed:.1f}%)"
        else:
            return f"{self.edge.node_end.name} --> {self.edge.node_start.name} ({-100 * self.passed:.1f}%)"


class IcebreakerState(ShipState):
    """
    State of an icebreaker.

    Attributes:
        ships: Attached ships.
    """
    ships: list[str]

    def __init__(self, node: routs.Node):
        super().__init__(node)
        self.ships = []


class FleetState:
    """
    State of the whole fleet.
    """
    icebreakers: dict[str, IcebreakerState]
    transports: dict[str, TransportShipState]

    def __init__(self, icebreaker_states: dict[str, IcebreakerState], transport_states: dict[str, TransportShipState]):
        self.icebreakers = icebreaker_states
        self.transports = transport_states
